the introspection cache and buildkey solution#1304
Conversation
the introspection cache and buildkey solution
| if (typeof opts.connectionString === 'string') { | ||
| try { | ||
| const url = new URL(opts.connectionString); | ||
| const host = url.hostname || 'localhost'; |
There was a problem hiding this comment.
these types of defaults should be done the way we do other pgpmjs/types or pgpmjs/env — and I think we have the same for our graphql server, env/types
https://github.com/constructive-io/constructive/tree/main/graphql/env
https://github.com/constructive-io/constructive/tree/main/graphql/types
| try { | ||
| const url = new URL(opts.connectionString); | ||
| const host = url.hostname || 'localhost'; | ||
| const port = url.port || '5432'; |
| * 1. connectionString-based (production — via pg-cache's getPgPool) | ||
| * 2. individual fields (fallback for pools created with explicit fields) | ||
| */ | ||
| export function getPoolIdentity(pool: Pool): string { |
There was a problem hiding this comment.
this also feels like a utility, would we use this anywhere else?
|
Review the following changes in direct dependencies. Learn more about Socket for GitHub.
|
|
We just pushed the full multi-tenant capacity program to #1325 (measured on a production-shaped rig: 48 tenant DBs, 61k First — this PR's skeleton is the right shape, and #1325 independently converged on the same one: normalized build-input key + single-flight creation + svc_key→key mappings with epoch/per-database flush. The disposal WeakSet double-release guard matches what we ended up with too. Three measured differences that changed our conclusion: 1. Sharing scope. 2. Introspection cost. Unless we misread the diff, there's no introspection caching in this PR (the "introspect" hits are the buildKey doc comment and the perf tooling's schema discovery) — every handler build still runs full-catalog introspection and retains the whole graph. That cost turned out to be the wall, and it's fixable independently of the caching strategy: #1325 rewrites the introspection SQL pre-parse to only the namespaces the instance serves → 1,305.6MB → 14.7MB retained per instance (87×), cold build 7.2s → 0.42s, PG-side spike +1,283MiB → +17MiB. Notably, 3. Cache bounds under ~GB entries. Practical notes:
Full methodology and raw numbers: |
This PR implements a new multi-tenancy optimization strategy without changing Graphile/Crystal internals, centered on exact-match buildKey-based handler reuse. Build keys are derived from connection identity, schemas, and role inputs, allowing requests with identical build inputs to share the same Graphile handler while preserving strict isolation semantics. The PR also adds perf stress-test coverage, including shape-variant perf tooling, so the new caching path can be exercised and evaluated under load without reintroducing template sharing or SQL rewriting.